/* 
 * File:   Solver.h
 * Author: Kenley
 *
 * Created on October 12, 2012, 9:56 AM
 * 
 * Some notes for developers reference:
 * An expression is a set of numbers, variables, operations, and functions. But
 * not a equal sign. Ex 0+0, 7x+5, 4*abs(x)+sin(90)
 * An equation sets a variable or expression equal to another expression.
 * Ex 0=7x+5 x=55, j=u+8-6*abs(h)
 * A function is a type of equation that is all about inputs and outputs.

 */

#ifndef SOLVER_H
#define	SOLVER_H

#include <string>
#include <map>
#include <set>

using namespace std;

class Solver {
public:
    Solver();
    virtual ~Solver();

//    enum math_element {
//        expression,
//        equation,
//        function,
//        number,
//        variable,
//        operation
//    };
    
    /**
     * Solves an equation for a variable. If the variable is not found in the 
     * equation the equation will be returned unchanged.
     * 
     * @param equation is a string containing the ASCII formated equation to solve.
     * @param varable is a string containing the variable.
     * @return an equation solved for "variable".
     */
    string solveFor(string equation, string variable) const;

    /**
     * Solves an equation or expression for a numerical solution. If 'equation' is
     * an equation all variables except one must be defined in the 'variables' map.
     * If 'equation' is an expression (i.e. no =) and all variables are defined
     * in the 'variables' map then the solution will be returned. If one variable
     * is left the expression will be set to zero and solved for that variable.
     * Any equation or expression that cannot be returned as a number as described
     * above will return as an equation still.
     * 
     * @throw if not enough information is given to find a numerical solution.
     * @param equation is a string containing the ASCII formated equation or expression to solve.
     * @param varables is a map containing the variables and their values.
     * @return a set of answers as strings, in fraction form if possible.
     */
    string solveExact(string equation, map<string, string> variables) const;
    
    /**
     * Same as solveExact but returns answer in decimal form.
     * 
     * @throw if not enough information is given to find a numerical solution.
     * @param equation is a string containing the ASCII formated equation or expression to solve.
     * @param varables is a map containing the variables and their values.
     * @return a set of answers as strings, in decimal form.
     */
    set<string> solveApproximate(string equation, map<string, string> variables) const;

    /**
     * Replace a variable with an expression or number in equation. There is no
     * guarantee about weather or not any simplifications will be done.
     * 
     * @throw one of the parameters passed in is not correct or replacement is not successful.
     * @param equation is a string containing an ASCII formated equation.
     * @param varables the variable to be removed and replaced with expression.
     * @param expression the expression to place instead of variable.
     * @return a new equation with variable replaced with expression.
     */
    string replace(string equation, string variable, string expression) const;

    /**
     * This command simplifies the given expressions to the smallest possible,
     * easily readable expression. 
     * 
     * @throw 
     * @param equation an equation or expression to simplify.
     * @return the simplified expression.
     */
    string simplify(const string& equation) const;

    /**
     * getVariables will return a list with all the variables in it
     * ?? TODO update these notes
     * 
     * @throw 
     * @param equation an equation or expression to simplify.
     * @return the simplified expression.
     */
    set<string> getVariables(string equation) const;

private:
    Solver(const Solver& orig);

};

#endif	/* SOLVER_H */

